home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / Tickle-4.0 (tcl) / tcl / expecTerm / pty_unicos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  5.4 KB  |  247 lines  |  [TEXT/MPS ]

  1. /* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */
  2.  
  3. /*
  4.  
  5. Original by: Don Libes, NIST, 2/6/90
  6. Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA,  1/10/91
  7. Hacked for Unicos 6.0 by: Pete TerMaat, pete@willow.cray.com, 3/27/91
  8.  
  9. Design and implementation of this program was paid for by U.S. tax
  10. dollars.  Therefore it is public domain.  However, the author and NIST
  11. would appreciate credit if this program or parts of it are used.
  12.  
  13. */
  14.  
  15. #include <unistd.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <sys/ioctl.h>
  19. #include <sys/file.h>
  20. #include <sys/fcntl.h>
  21. #if CRAY>=60
  22. #include <sys/termios.h>
  23. #else
  24. #include <sys/termio.h>
  25. #endif /* 60 */
  26. #if CRAY>=70 && defined(_CRAY2)
  27. #include <sys/session.h>
  28. #endif /* 70 */
  29. #include <sys/pty.h>
  30. #include <pwd.h>
  31. #include <utmp.h>
  32. #include <signal.h>
  33. #include "translate.h"
  34.  
  35. void debuglog();
  36. #if CRAY<60
  37. extern int fork(), execl(), wait();
  38. #endif
  39.  
  40. #ifndef TRUE
  41. #define TRUE 1
  42. #define FALSE 0
  43. #endif
  44.  
  45. static char    linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
  46. static char    linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
  47. static int    lowpty;
  48. static int    highpty;
  49. static int    realuid;
  50. static int    realgid;
  51.  
  52. static void
  53. pty_stty(s,name)
  54. char *s;        /* args to stty */
  55. char *name;        /* name of pty */
  56. {
  57. #define MAX_ARGLIST 10240
  58.     char buf[MAX_ARGLIST];    /* overkill is easier */
  59.  
  60.     sprintf(buf,"stty %s < %s > %s",s,name,name);
  61.     system(buf);
  62. }
  63.  
  64. struct    termio exp_tty_original;
  65.  
  66. #define GET_TTYTYPE    0
  67. #define SET_TTYTYPE    1
  68. static void
  69. ttytype(request,fd,s)
  70. int request;
  71. int fd;
  72. char *s;    /* stty args, used only if request == SET_TTYTYPE */
  73. {
  74.     static int is_a_tty;
  75.  
  76.     if (request == GET_TTYTYPE) {
  77.         if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) {
  78.             is_a_tty = FALSE;
  79.         } else is_a_tty = TRUE;
  80.     } else {    /* type == SET_TTYTYPE */
  81.         if (is_a_tty) {
  82.             (void) ioctl(fd, TCSETA, (char *)&exp_tty_original);
  83.         } else {
  84.             /* if running in the background, we have no access */
  85.             /* to a a tty to copy parameters from, so use ones */
  86.             /* supplied by original Makefile */
  87.             debuglog("getptyslave: (default) stty %s\n",DFLT_STTY);
  88.             pty_stty(DFLT_STTY,linet);
  89.         }
  90.         if (s) {
  91.             /* give user a chance to override any terminal parms */
  92.             debuglog("getptyslave: (user-requested) stty %s\n",s);
  93.             pty_stty(s,linet);
  94.         }
  95.     }
  96. }
  97.  
  98. void
  99. init_pty()
  100. {
  101.     lowpty=0;
  102. #ifdef _SC_CRAY_NPTY
  103.     highpty=sysconf(_SC_CRAY_NPTY);
  104. #else
  105.     highpty=128;
  106. #endif /* _SC_CRAY_NPTY */
  107.  
  108.      realuid=getuid();    /* get REAL uid */
  109.      realgid=getgid();    /* get REAL uid */
  110.      setgid(0);        /* Set REAL gid */
  111.      setuid(0);        /* Set REAL uid to root also */
  112.      setegid(realgid);     /* Don't run as root! */
  113.      seteuid(realuid);     /* Don't run as root! */
  114.  
  115.     ttytype(GET_TTYTYPE,0,(char *)0);
  116. }
  117.  
  118. /* returns fd of master end of pseudotty */
  119. int
  120. getptymaster()
  121. {
  122.     struct stat sb;
  123.     int master;
  124.     int npty;
  125.  
  126.     for (npty = lowpty; npty <= highpty; npty++) {
  127.         seteuid(0); /* we need to be root! */
  128.         (void) sprintf(linep, "/dev/pty/%03d", npty);
  129.         master = open(linep, O_RDWR);
  130.  
  131.         if (master < 0)
  132.             continue;
  133.  
  134.         (void) sprintf(linet, "/dev/ttyp%03d", npty);
  135.         if(stat(linet, &sb) < 0) {
  136.             (void) close(master);
  137.             continue;
  138.         }
  139.         if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
  140.                         chown(linet, realuid, realgid);
  141.                         chmod(linet, 0600);
  142.                         (void)close(master);
  143.                         master = open(linep, 2);
  144.                         if (master < 0)
  145.                                 continue;
  146.                 }
  147.         setegid(realgid);
  148.         seteuid(realuid); /* back to who we are! */
  149.         if (access(linet, R_OK|W_OK) != 0) {
  150.             (void) close(master);
  151.             continue;
  152.         }
  153.         return(master);
  154.     }
  155.     return(-1);
  156. }
  157.  
  158. int
  159. getptyslave(stty_args)
  160. char *stty_args;
  161. {
  162.     int slave;
  163.  
  164.     if (0 > (slave = open(linet, O_RDWR))) return(-1);
  165.  
  166.     /* sanity check - if slave not 0, skip rest of this and return */
  167.     /* to what will later be detected as an error in caller */
  168.     if (0 != slave) return(slave);
  169.  
  170.     fcntl(0,F_DUPFD,1);    /* duplicate 0 onto 1 to prepare for stty */
  171.     ttytype(SET_TTYTYPE,slave,stty_args);
  172.     return(slave);
  173. }
  174. setptyutmp()
  175. {
  176.     struct utmp utmp;
  177.     struct passwd *pw;
  178.  
  179.     seteuid(0);
  180.     (void) setutent ();
  181.     /* set up entry to search for */
  182.     (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
  183.          sizeof (utmp.ut_id));
  184.     utmp.ut_type = DEAD_PROCESS;
  185.  
  186.     /* position to entry in utmp file */
  187.     if( 0 == getutid(&utmp)) {
  188.         seteuid(realuid);
  189.         return(-1);    /* no utmp entry for this line ??? */
  190.     }
  191.  
  192.     /* set up the new entry */
  193.     pw = getpwuid(realuid);
  194.     utmp.ut_type = USER_PROCESS;
  195.     utmp.ut_exit.e_exit = 2;
  196.     (void) strncpy(utmp.ut_user,
  197.         (pw && pw->pw_name) ? pw->pw_name : "????",
  198.         sizeof(utmp.ut_user));
  199.  
  200.     (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
  201.         sizeof(utmp.ut_id)); 
  202.  
  203.     gethostname(utmp.ut_host, sizeof(utmp.ut_host));
  204.     (void) strncpy (utmp.ut_line,
  205.         linet + strlen("/dev/"), sizeof (utmp.ut_line));
  206.     utmp.ut_pid = getpid();
  207.     utmp.ut_time = time ((long *) 0);
  208.  
  209.     /* write out the entry */
  210.     pututline(&utmp);
  211.  
  212.     /* close the file */
  213.     (void) endutent();
  214.     seteuid(realuid);
  215.     return(0);
  216. }
  217.  
  218. int
  219. system(s)
  220. char    *s;
  221. {
  222.     int    status, pid, w;
  223.     register void (*istat)(), (*qstat)();
  224.  
  225.     if((pid = fork()) == 0) {
  226.         fixids();
  227.         (void) execl("/bin/sh", "sh", "-c", s, 0);
  228.         _exit(127);
  229.     }
  230.     if (pid == -1)
  231.         return(-1);
  232.     istat = signal(SIGINT, SIG_IGN);
  233.     qstat = signal(SIGQUIT, SIG_IGN);
  234.     while((w = wait(&status)) != pid && w != -1)
  235.         ;
  236.     (void) signal(SIGINT, istat);
  237.     (void) signal(SIGQUIT, qstat);
  238.     return((w == -1)? w: status);
  239. }
  240.  
  241. fixids()
  242. {
  243.     seteuid(0);
  244.     setgid(realgid);
  245.     setuid(realuid);
  246. }
  247.